import tkinter as tk
from tkinter import ttk
import webbrowser
from tkModelFrame.commonmodels import *
from tkModelFrame.defaultpic import DefaultPicture
import os

class WorkingSpace(tk.Frame):
    def __init__(self, root, fatherworkingspace, name:str):
        super(WorkingSpace, self).__init__(root)
        self.ws = tk.Frame(self)
        self.name = name
        self.namelabel = tk.Label(self, text=name, font=("黑体",16))
        if issubclass(fatherworkingspace.__class__, WorkingSpace):
            self.fatherpointertree = fatherworkingspace.fatherpointertree[:]
            self.fatherpointertree.append(fatherworkingspace.name)
            fatherworkingspace.subworkingspace.append(name)
        elif name == "主菜单" :
            self.fatherpointertree = ["root"]
        elif name == "正在施工，博士还不能休息！":
            self.fatherpointertree = ["root","主菜单"]
        self.subworkingspace = []
        self.subwsnum = len(self.subworkingspace)
        self.subpointer = "self"
        self.namelabel.pack(fill="x",pady=5)
        self.ws.pack(pady=5)


    def displace(self):
        self.pack_forget()

    def place(self):
        self.pack(pady=5)
        pass

    def wsappend(self, ws):
        if issubclass(ws.__class__, WorkingSpace):
            self.subworkingspace[ws.name] = ws
            self.subwsnum = len(self.subworkingspace)
        pass


class MainWorkingSpace(WorkingSpace):
    def __init__(self, root, buttoncallback = print, helpurl = None, wslist = () ):
        self.helpurl = helpurl
        self.wslist = wslist
        WorkingSpace.__init__(self, root, root, "主菜单")

        for ws in wslist:
            tk.Button(self.ws, width = 20, text = ws, command=lambda x=ws:buttoncallback(x)).pack(fill="x", pady=5)
            pass
        if helpurl is not None:
            tk.Button(self.ws, width = 20, text = "帮助文档", command=self.visithelpurl).pack(fill="x", pady=5)
            pass

    def visithelpurl(self):
        webbrowser.open(self.helpurl, new=0, autoraise=True)

class NewWorkingSpace(WorkingSpace):
    def __init__(self, rf, fatherWSname:str, thisWSname:str):
        WorkingSpace.__init__(self,rf.root, rf.workingspacedict[fatherWSname], thisWSname)
        rf.wsappend(self)
        pass


class GuidingMenuModel():
    def __init__(self, fathermenu, workingspace = None, RF = None):
        self.father = fathermenu
        self.workingspace = workingspace
        self.menu = None
        self.submenu = {}
        self.command = lambda :RF.reshowworkingspace(self.workingspace.name)
        if fathermenu.__class__ == tk.Menu:
            self.menu = tk.Menu(fathermenu, tearoff=False)
            self.menu.add_command(label=self.workingspace.name, command=self.command)
            if len(self.workingspace.subworkingspace) > 0:
                for n in self.workingspace.subworkingspace:
                    self.submenu[n] = GuidingMenuModel(self, RF.workingspacedict[n], RF)
                self.father.add_cascade(label="导航栏", menu=self.menu)
            else:
                self.father.add_command(label=">> "+self.workingspace.name, command=self.command)
        elif fathermenu.__class__ == GuidingMenuModel:
            if len(self.workingspace.subworkingspace) > 0:
                self.menu = tk.Menu(self.father.menu, tearoff=False)
                self.menu.add_command(label=">> "+self.workingspace.name, command=self.command)
                self.menu.add_separator()
                for n in self.workingspace.subworkingspace:
                    self.submenu[n] = GuidingMenuModel(self, RF.workingspacedict[n], RF)
                self.father.menu.add_cascade(label=self.workingspace.name, menu=self.menu)
            else:
                self.father.menu.add_command(label=">> "+self.workingspace.name, command=self.command)


class ToppingLabel:
    def __init__(self, root, toppingtext = "RootFrame", editor = ""):
        self.tf = tk.Frame(root)
        tk.Label(self.tf,text = "", font=("黑体",5)).pack(fill="x")
        tk.Label(self.tf,text = toppingtext, font=("黑体",20)).pack(fill="x",pady=5)
        if editor != "":
            tk.Label(self.tf,text = f"创作者：{editor}").pack(fill="x")
        tk.Label(self.tf,text = "", font=("黑体",5)).pack(fill="x")

    def resetwsname(self, newwsname):
        self.wsname.set(newwsname)

    def place(self):
        self.tf.pack(pady=15)
    def displace(self):
        self.tf.pack_forget()

class RFDataBase:
    def __init__(self,  rftitle = "tk", rfsize = "360x420", toppingtext = "RootFrame", editor = "", helpurl = None,
                 rootwslist = (), toppingstate = 'always', guidingmenu = True):
        self.rftitle = rftitle
        self.rfsize = rfsize
        self.toppingtext = toppingtext
        self.editor = editor
        self.rootwslist = rootwslist
        self.workingspacedict = {}
        self.helpurl = helpurl
        self.extraquitfunctions = {}
        self.toppingstate = toppingstate
        self.guidingmenu = guidingmenu
        #这一行是有问题的

        self.defaultphoto = tk.PhotoImage(file=DefaultPicture.create())
        DefaultPicture.delete()


    def printRFData(self):
        for i in self.__dict__:
            if i in ("__module__", "__doc__"):
                continue
            if len(str(self.__dict__[i])) > 8 and "objects" in str(self.__dict__[i]):
                continue
            print(f"'{i}':{self.__dict__[i]},")


class RootFrame(RFDataBase):
    def __init__(self, **RF_initDict):

        self.root = tk.Tk()

        #数据存储在父类
        super(RootFrame, self).__init__( **RF_initDict)
        # RFDataBase.__init__(self, self.root, rftitle=rftitle, rfsize=rfsize, toppingtext=toppingtext,
        #                     editor=editor, helpurl=helpurl,
        #                     rootwslist=rootwslist, userdata=userdata, uservariabledata=uservariabledata,
        #                     picaddrlist = picaddrlist)

        #显示组件放在这里
        self.toppinglabel = ToppingLabel(self.root, self.toppingtext, self.editor)
        self.mainworkingspace = MainWorkingSpace(self.root, helpurl=self.helpurl, wslist=self.rootwslist, buttoncallback= self.reshowworkingspace)
        self.defaultworkingspace = self._set_defaultworkingspace()

        self.returnbutton = tk.Button(self.root, width = 20, text = "返回", command=self.quitcallback, background='#BFEFFF')
        self.quitbutton = tk.Button(self.root, width = 20, text = "退出", command=self.quitcallback, background='#BFEFFF')
        self.topmenu = tk.Menu(self.root)

        for rootws in self.rootwslist :
            self.workingspacedict[rootws] = self.defaultworkingspace

        #控制组件放在这里
        self.wspointer = self.mainworkingspace.name
        self.workingspacedict[self.mainworkingspace.name] = self.mainworkingspace
        self.workingspacedict[self.defaultworkingspace.name] = self.defaultworkingspace

        self.fatherpointertree = self.mainworkingspace.fatherpointertree

        #调整根窗口参数
        self.root.title(self.rftitle)
        self.root.geometry(self.rfsize)

        #新增导航栏

        #放置显示组件
        self.reshowworkingspace(self.mainworkingspace.name)

    def _set_defaultworkingspace(self):
        ws_zero = WorkingSpace(self.root,self.root, "正在施工，博士还不能休息！")
        tk.Label(ws_zero.ws, image=self.defaultphoto, width=150, height = 150).pack()
        return ws_zero

    def _place_quitbutton(self):
        if self.wspointer == self.mainworkingspace.name:
            self.returnbutton.pack_forget()
            self.quitbutton.pack(pady=15, side="bottom")
        else:
            self.quitbutton.pack_forget()
            self.returnbutton.pack(pady=15, side="bottom")


    def wsappend(self, ws):
        if issubclass(ws.__class__, WorkingSpace):
            self.workingspacedict[ws.name] = ws
            return True
        elif(ws.name == self.mainworkingspace.name):
            self.workingspacedict[ws.name] = ws
        else:
            return False

    def reshowworkingspace(self, newpagepointer):
        self.toppinglabel.displace()
        self.workingspacedict[self.wspointer].displace()
        if newpagepointer in self.workingspacedict.keys():
            self.wspointer = newpagepointer
        else:
            self.wspointer = self.defaultworkingspace.name
        if self.toppingstate == 'always' or self.wspointer == '主菜单':
            self.toppinglabel.place()
        self.workingspacedict[self.wspointer].place()
        self.fatherpointertree = self.workingspacedict[self.wspointer].fatherpointertree
        self._place_quitbutton()
        print("\n--------------------------------------------------------")
        print("Action:切换新界面")
        print(f"当前指针为：{self.wspointer}")
        print(f"当前指针树为：{self.fatherpointertree}")
        print("--------------------------------------------------------")

    def quitcallback(self):
        if self.wspointer == '主菜单':
            self.root.destroy()
            self.root.quit()
            print("下班！")
        else:
            wspointer = str(self.wspointer) #当返回键被绑定至跳转至其他页面时，禁用换页功能
            if self.wspointer in self.extraquitfunctions.keys():
                self.extraquitfunctions[self.wspointer]()
            if wspointer == self.wspointer:
                self.reshowworkingspace(self.fatherpointertree[-1])
    def addquitfunc(self,ws = "正在施工，博士还不能休息！", command = lambda :print("博士如果不加班完成工作，凯尔希医生就生气了！！！")):
        if callable(command) and ws in self.workingspacedict.keys():
            self.extraquitfunctions[ws] = command

    def add_menu(self, menu=None, name="新建菜单"):
        self.topmenu.add_cascade(label=name, menu=menu)

    def mainloop(self):
        if self.guidingmenu:
            tpm = GuidingMenuModel(self.topmenu, self.mainworkingspace, RF=self)
            self.root["menu"] = self.topmenu
        self.root.mainloop()




if __name__ == "__main__":
    RF_initDict = {
        'rftitle': 'PRTS',  # 窗口名字
        'rfsize': "360x420",  # 窗口尺寸
        'toppingtext': "罗德岛次世代GUI技术",  # 置顶标签名
        'editor': "DG_JiuYuan",  # 作者名字
        'wsnamelist': ('W酱发癫现场', '未编辑工作区示例'),  # 工作区的名字
        'userdata': {'_userkey': '_uservalue'},  # 导入用户自定义数据，采用键值对形式传入并索引
        'helpurl': 'https://prts.wiki/w/%E9%A6%96%E9%A1%B5',  # 在线帮助文档链接，不传入该参数则不布置帮助按键
        'uservariabledata': {},  # 导入用户需要的tkVar格式的变量，同样以键值对导入并索引
        'picaddrlist': ["w1.gif", "w.gif"]  # 需要使用到的图片
    }

    # RF = RootFrame(**RF_initDict)
    #
    #
    # def runaway():
    #     RF.reshowworkingspace("快跑")
    #
    #
    # # 建立新的工作区
    # # 参数：root,name
    # wfadian = NewWorkingSpace(RF, "主菜单", 'W酱发癫现场')
    # # # 工作区类的属性ws是一个tkinter.Frame, 编辑方法与一般的Frame完全相同
    # tk.Label(wfadian.ws, image=RF.pictures[0], width=150, height=150).pack()
    # tk.Button(wfadian.ws, text="W 正在发癫！！！快跑啊！！！", command=runaway).pack()
    #
    # kuaipao = NewWorkingSpace(RF, 'W酱发癫现场', '快跑')
    # tk.Label(kuaipao.ws, image=RF.pictures[1], width=150, height=150).pack()
    # tk.Label(kuaipao.ws, text="跑反了，你要被吃掉啦！！！").pack()
    # print(wfadian.subworkingspace)
    # print(kuaipao.subworkingspace)
    #
    # RF.mainloop()


